﻿/*
* Copyright (c) 2010-2012 Tesla Engine Group
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/


using System;
using Tesla.Math;

namespace Tesla.Graphics {
    internal struct MaterialParameter {
        private MaterialParameterType _type;
        private IEffectParameter _cachedParameter;
        private String _name;
        private bool _isSemantic;
        
        //Possible values
        private float _singleValue;
        private int _intValue;
        private bool _boolValue;
        private Vector2 _vector2Value;
        private Vector3 _vector3Value;
        private Vector4 _vector4Value;
        private Texture _textureValue;
        private Matrix _matrixValue;

        public MaterialParameterType ParameterType {
            get {
                return _type;
            }
        }

        public IEffectParameter EffectParameter {
            get {
                return _cachedParameter;
            }
        }

        public String Name {
            get {
                return _name;
            }
        }

        public bool IsSemantic {
            get {
                return _isSemantic;
            }
        }

        public float SingleValue {
            get {
                return _singleValue;
            }
        }

        public int IntValue {
            get {
                return _intValue;
            }
        }

        public bool BoolValue {
            get {
                return _boolValue;
            }
        }

        public Vector2 Vector2Value {
            get {
                return _vector2Value;
            }
        }

        public Vector3 Vector3Value {
            get {
                return _vector3Value;
            }
        }

        public Vector4 Vector4Value {
            get {
                return _vector4Value;
            }
        }

        public Texture TextureValue {
            get {
                return _textureValue;
            }
        }

        public Matrix MatrixValue {
            get {
                return _matrixValue;
            }
        }

        public MaterialParameter(MaterialParameter param) {
            _type = param.ParameterType;
            _cachedParameter = param.EffectParameter;
            _name = param.Name;
            _isSemantic = param.IsSemantic;
            _singleValue = param.SingleValue;
            _intValue = param.IntValue;
            _boolValue = param.BoolValue;
            _vector2Value = param.Vector2Value;
            _vector3Value = param.Vector3Value;
            _vector4Value = param.Vector4Value;
            _textureValue = param.TextureValue;
            _matrixValue = param.MatrixValue;
        }

        public MaterialParameter(MaterialParameter param, IEffectParameter replacement) {
            _type = param.ParameterType;
            _cachedParameter = replacement;
            _name = param.Name;
            _isSemantic = param.IsSemantic;
            _singleValue = param.SingleValue;
            _intValue = param.IntValue;
            _boolValue = param.BoolValue;
            _vector2Value = param.Vector2Value;
            _vector3Value = param.Vector3Value;
            _vector4Value = param.Vector4Value;
            _textureValue = param.TextureValue;
            _matrixValue = param.MatrixValue;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, bool value) {
            _type = MaterialParameterType.Bool;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = value;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, int value) {
            _type = MaterialParameterType.Int32;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = value;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, float value) {
            _type = MaterialParameterType.Single;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = value;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, Vector2 value) {
            _type = MaterialParameterType.Vector2;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = value;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, Vector3 value) {
            _type = MaterialParameterType.Vector3;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = value;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, Vector4 value) {
            _type = MaterialParameterType.Vector4;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = value;
            _textureValue = null;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, Texture value) {
            _type = MaterialParameterType.Texture;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = value;
            _matrixValue = Matrix.Identity;
        }

        public MaterialParameter(IEffectParameter param, String name, bool isSemantic, Matrix value) {
            _type = MaterialParameterType.Matrix;
            _cachedParameter = param;
            _isSemantic = isSemantic;
            _name = name;
            _singleValue = 0;
            _intValue = 0;
            _boolValue = false;
            _vector2Value = Vector2.Zero;
            _vector3Value = Vector3.Zero;
            _vector4Value = Vector4.Zero;
            _textureValue = null;
            _matrixValue = value;
        }
    }

    /// <summary>
    /// Material Parameter type enumeration.
    /// </summary>
    internal enum MaterialParameterType {
        /// <summary>
        /// Float parameter.
        /// </summary>
        Single,

        /// <summary>
        /// Int32 parameter.
        /// </summary>
        Int32,

        /// <summary>
        /// Boolean parameter.
        /// </summary>
        Bool,

        /// <summary>
        /// Vector2 parameter.
        /// </summary>
        Vector2,

        /// <summary>
        /// Vector3 parameter.
        /// </summary>
        Vector3,

        /// <summary>
        /// Vector4 parameter.
        /// </summary>
        Vector4,

        /// <summary>
        /// Texture parameter.
        /// </summary>
        Texture,

        /// <summary>
        /// Matrix parameter.
        /// </summary>
        Matrix
    }
}
